package com.wolfcode.appointment.service.impl;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.wolfcode.appointment.domain.info.ServiceItemAuditInfo;
import com.wolfcode.appointment.domain.vo.BusServiceItemAuditVo;
import com.wolfcode.appointment.domain.vo.BusServiceItemVo;
import com.wolfcode.appointment.enums.AuditEnum;
import com.wolfcode.appointment.enums.CarPackageEnum;
import com.wolfcode.appointment.enums.SaleEnum;
import com.wolfcode.audit.domain.BusCarPackageAudit;
import com.wolfcode.audit.enums.PackageAuditEnum;
import com.wolfcode.audit.service.IBusCarPackageAuditService;
import com.wolfcode.common.core.domain.entity.SysUser;
import com.wolfcode.common.utils.ActivitiesUtils;
import com.wolfcode.common.utils.DateUtils;
import com.wolfcode.common.utils.SecurityUtils;
import com.wolfcode.flow.domain.BusBpmnInfo;
import com.wolfcode.flow.mapper.BusBpmnInfoMapper;
import com.wolfcode.system.service.ISysUserService;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wolfcode.appointment.mapper.BusServiceItemMapper;
import com.wolfcode.appointment.domain.BusServiceItem;
import com.wolfcode.appointment.service.IBusServiceItemService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * 服务项Service业务层处理
 * 
 * @author wolfcode
 * @date 2022-11-22
 */
@Service
public class BusServiceItemServiceImpl implements IBusServiceItemService 
{
    @Autowired
    private BusServiceItemMapper busServiceItemMapper;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private BusBpmnInfoMapper busBpmnInfoMapper;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private IBusCarPackageAuditService busCarPackageAuditService;
    /**
     * 查询服务项
     * 
     * @param id 服务项主键
     * @return 服务项
     */
    @Override
    public BusServiceItem selectBusServiceItemById(Long id)
    {
        return busServiceItemMapper.selectBusServiceItemById(id);
    }

    /**
     * 查询服务项列表
     * 
     * @param busServiceItem 服务项
     * @return 服务项
     */
    @Override
    public List<BusServiceItem> selectBusServiceItemList(BusServiceItem busServiceItem)
    {
        return busServiceItemMapper.selectBusServiceItemList(busServiceItem);
    }

    /**
     * 新增服务项
     * 
     * @param
     * @return 结果
     */
    @Override
    public int insertBusServiceItem(BusServiceItemVo busServiceItemvo)
    {
        Assert.notNull(busServiceItemvo,"非法参数");
        //用不用判断负数：答案用
        //折扣价不能大于原价
        Assert.state(busServiceItemvo.getOriginalPrice()
                .compareTo(busServiceItemvo.getDiscountPrice())>=0,
                "折扣价不能大于原价");
        BusServiceItem busServiceItem=new BusServiceItem();
        BeanUtils.copyProperties(busServiceItemvo,busServiceItem);
        //设置审核状态,判断是否是套餐
        boolean isCarPackage=busServiceItemvo.getCarPackage()== CarPackageEnum.YES.ordinal();
        busServiceItem.setAuditStatus(isCarPackage?AuditEnum.INIT.ordinal():
                AuditEnum.NO_AUDIT.ordinal());
        //设置上下架状态，默认未上架
        busServiceItem.setSaleStatus(SaleEnum.NO.ordinal());
        busServiceItem.setCreateTime(DateUtils.getNowDate());
        return busServiceItemMapper.insertBusServiceItem(busServiceItem);
    }

    /**
     * 修改服务项
     * 
     * @param
     * @return 结果
     */
    @Override
    public int updateBusServiceItem(BusServiceItemVo busServiceItemVo)
    {
        Assert.notNull(busServiceItemVo,"非法参数");
        //折扣价不能大于原价
        Assert.state(busServiceItemVo.getOriginalPrice()
                        .compareTo(busServiceItemVo.getDiscountPrice())>=0,
                "折扣价不能大于原价");
        //1 查询数据库是否存在该服务单项目
        BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(busServiceItemVo.getId());
        // 除审核中状态，其他都可以编辑
        Assert.state(!(busServiceItem.getAuditStatus()==
                AuditEnum.AUDITING.ordinal()),"除审核中状态，其他都可以编辑");
        //上架中的状态，不可以编辑
        Assert.state(!(busServiceItem.getSaleStatus()==
                SaleEnum.YES.ordinal()),"上架中的状态，不可以编辑");

        BusServiceItem serviceItem=new BusServiceItem();
        BeanUtils.copyProperties(busServiceItemVo,serviceItem);
        // 相当于重置
        //设置审核状态,判断是否是套餐
        boolean isCarPackage=busServiceItemVo.getCarPackage()== CarPackageEnum.YES.ordinal();
        serviceItem.setAuditStatus(isCarPackage?AuditEnum.INIT.ordinal():
                AuditEnum.NO_AUDIT.ordinal());
        //设置上下架状态，默认未上架
        serviceItem.setSaleStatus(SaleEnum.NO.ordinal());
        //2 更新数据库
        return busServiceItemMapper.updateBusServiceItem(serviceItem);
    }

    /**
     * 批量删除服务项
     * 
     * @param ids 需要删除的服务项主键
     * @return 结果
     */
    @Override
    public int deleteBusServiceItemByIds(Long[] ids)
    {
        return busServiceItemMapper.deleteBusServiceItemByIds(ids);
    }

    /**
     * 删除服务项信息
     * 
     * @param id 服务项主键
     * @return 结果
     */
    @Override
    public int deleteBusServiceItemById(Long id)
    {
        return busServiceItemMapper.deleteBusServiceItemById(id);
    }
    // 下架状态---点一下---上架状态
    @Override
    public void saleOn(Long id) {
        Assert.notNull(id,"非法参数");
        BusServiceItem busServiceItem = busServiceItemMapper.selectBusServiceItemById(id);
        // 已经上架状态，不处理，直接返回
        if(busServiceItem.getSaleStatus()==SaleEnum.YES.ordinal()) return;
        // 假如是套餐并且审核通过才可以上架
        // 无需审核也可以上架
        boolean pass=(busServiceItem.getCarPackage()==CarPackageEnum.YES.ordinal()
                && busServiceItem.getAuditStatus()==AuditEnum.PASS.ordinal())
                || busServiceItem.getAuditStatus()==AuditEnum.NO_AUDIT.ordinal();

        Assert.state(pass,"套餐并且审核通过才可以上架或无需审核也可以上架");
        // 更新上架状态
        BusServiceItem serviceItem=new BusServiceItem();
        serviceItem.setId(id);
        serviceItem.setSaleStatus(SaleEnum.YES.ordinal());
        busServiceItemMapper.updateBusServiceItem(serviceItem);
    }
    // 上架---点击---下架
    @Override
    public void saleOff(Long id) {
        Assert.notNull(id,"非法参数");
        BusServiceItem serviceItem=new BusServiceItem();
        serviceItem.setId(id);
        serviceItem.setSaleStatus(SaleEnum.NO.ordinal());
        busServiceItemMapper.updateBusServiceItem(serviceItem);
    }

    @Override
    public ServiceItemAuditInfo auditInfo(Long id) {
        //构建Info返回
        //1 获取服务单项
        BusServiceItem busServiceItem = selectBusServiceItemById(id);
        Assert.notNull(busServiceItem,"非法参数");

        //2 在套餐,未上架,初始化，审批拒绝状态才可审核
        Integer carPackage = busServiceItem.getCarPackage();
        Integer saleStatus = busServiceItem.getSaleStatus();
        Integer auditStatus = busServiceItem.getAuditStatus();
        Assert.state(CarPackageEnum.YES.ordinal()==carPackage,"套餐才可以审核");
        Assert.state(SaleEnum.NO.ordinal()==saleStatus,"未上架状态才可审核");
        Assert.state(AuditEnum.INIT.ordinal()==auditStatus ||
                AuditEnum.REJECT.ordinal()==auditStatus,"审批为初始化，审批状态才可审核");

        ServiceItemAuditInfo auditInfo=new ServiceItemAuditInfo();
        auditInfo.setServiceItem(busServiceItem);
        //2 查询店主角色用户
        List<SysUser> showOwner = userService.queryByRoleKey("shopOwner");
        auditInfo.setShopOwners(showOwner);

        //3 假如符合业务，价格大于等于3000，查询财务角色信息
        //TODO 0代表是服务套餐类型
        BusBpmnInfo busBpmnInfo = busBpmnInfoMapper.getByBpmnType(0);
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey(busBpmnInfo.getProcessDefinitionKey())
                .processDefinitionVersion(busBpmnInfo.getVersion().intValue()).singleResult();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
        //获取流程定义折扣价格
        BigDecimal discountPrice = ActivitiesUtils.getGTEDiscountPrice(bpmnModel, busBpmnInfo.getProcessDefinitionKey());
        auditInfo.setDiscountPrice(discountPrice);
        //对比服务项的折扣价和流程定义的价格
        if(busServiceItem.getDiscountPrice().compareTo(discountPrice)>=0){
            List<SysUser> finances = userService.queryByRoleKey("financial");
            auditInfo.setFinances(finances);
        }
        return auditInfo;
    }

    @Override
    @Transactional
    public void startAudit(BusServiceItemAuditVo auditVo) {
        // 校验是否流程定义
        // TODO: 0 代表是服务套餐类型
        BusBpmnInfo busBpmnInfo = busBpmnInfoMapper.getByBpmnType(0);
        Assert.notNull(busBpmnInfo,"请先上传流程定义");
        //1 获取服务单项
        BusServiceItem busServiceItem = selectBusServiceItemById(auditVo.getId());
        Assert.notNull(busServiceItem,"非法参数");
        //2 在套餐,未上架,初始化，审批拒绝状态才可审核
        Integer carPackage = busServiceItem.getCarPackage();
        Integer saleStatus = busServiceItem.getSaleStatus();
        Integer auditStatus = busServiceItem.getAuditStatus();
        Assert.state(CarPackageEnum.YES.ordinal()==carPackage,"套餐才可以审核");
        Assert.state(SaleEnum.NO.ordinal()==saleStatus,"未上架状态才可审核");
        Assert.state(AuditEnum.INIT.ordinal()==auditStatus ||
                AuditEnum.REJECT.ordinal()==auditStatus,"审批为初始化，审批状态才可审核");

        // 2 开启套餐审核流程实例
        // 获取流程定义的key
        String processDefinitionKey = busBpmnInfo.getProcessDefinitionKey();
        // 业务标识BusinessKey(服务单项id)
        String businessKey=auditVo.getId().toString();
        // 存储流程定义变量
        Map<String,Object> params=new HashMap<>();
        params.put("shopOwnerId",auditVo.getShopOwnerId());
        if(auditVo.getFinanceId()!=null){
            params.put("financeId",auditVo.getFinanceId());
        }
        params.put("disCountPrice",busServiceItem.getDiscountPrice().longValue());
        // 开启流程实例对象
        ProcessInstance instance = runtimeService.
                startProcessInstanceByKey(processDefinitionKey,
                        businessKey,
                        params);

        // 3 添加审核套餐信息，更改状态
        // 3 保存套餐审核信息
        //封装CarPackageAudit对象
        BusCarPackageAudit audit = new BusCarPackageAudit();
        audit.setServiceItemId(busServiceItem.getId());
        audit.setServiceItemName(busServiceItem.getName());
        audit.setServiceItemPrice(busServiceItem.getDiscountPrice());
        audit.setServiceItemInfo(busServiceItem.getInfo());
        audit.setInfo(auditVo.getInfo());
        // 审核状态
        // 0,1
        audit.setStatus(PackageAuditEnum.AUDITING.ordinal());
        audit.setCreatorId(SecurityUtils.getUserId().toString());
        audit.setCreateTime(DateUtils.getNowDate());
        audit.setInstanceId(instance.getId());

        busCarPackageAuditService.insertBusCarPackageAudit(audit);
        // 4 更新服务单项状态为审核中
        BusServiceItem serviceItem=new BusServiceItem();
        serviceItem.setId(busServiceItem.getId());
        serviceItem.setAuditStatus(AuditEnum.AUDITING.ordinal());
        busServiceItemMapper.updateBusServiceItem(serviceItem);
    }
}
